package com.hexacta.radio.model;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;

public class Radio implements IObservable {
	
	private Long id;

	private static final String RADIO_OFF = "";

	private static final int SEEK_MOVEMENT = 5;
	private static final int DIAL_MOVEMENT = 1;

	private List<Dial> dials = new ArrayList<Dial>();
	private int dialIndex;

	private Boolean radioOn;

	private List<IObserver> observers = new ArrayList<IObserver>();

	public Radio(Boolean radioOn, List<Dial> dials) {
		this.dials = dials;
		this.dialIndex = 0;
		this.radioOn = radioOn;
	}

	public Radio() {
	}

	public void doDialUp(int dif) {
		if (radioOn) {
			this.dialIndex = this.dialIndex+=dif;
			if (this.dialIndex > this.dials.size() - 1) {
				this.dialIndex = 0;
			}
			this.notifyObservers();
		}
	}

	public void doDialDown(int dif) {
		if (radioOn) {
			this.dialIndex = this.dialIndex-=dif;
			if (this.dialIndex < 0) {
				this.dialIndex = this.dials.size() - 1;
			}
			this.notifyObservers();
		}
	}
	
	public void dialUp() {
		this.doDialUp(DIAL_MOVEMENT);
	}
	
	public void dialDown() {
		this.doDialDown(DIAL_MOVEMENT);
	}
	
	public void seekUp() {
		this.doDialUp(SEEK_MOVEMENT);
	}
	
	public void seekDown() {
		this.doDialDown(SEEK_MOVEMENT);
	}
	
	public void turnRadioOnOff(Boolean radioOn) {
		this.radioOn = radioOn;
		this.notifyObservers();
	}

	public String getStringDial() {
		return this.radioOn ? this.dials.get(dialIndex).getDisplay() : RADIO_OFF;
	}
	
	public Dial getSelectedDial() {
		return this.radioOn ? this.dials.get(dialIndex) : null;
	}
	
	private Dial getDial(final String dialString) {
		
		if(this.getSelectedDial().getDial().equals(dialString)) {
			return this.getSelectedDial();
		}
		else {
			return (Dial) CollectionUtils.find(this.dials, new Predicate() {
				
				@Override
				public boolean evaluate(Object dial) {
					return ((Dial) dial).getDial().equals(dialString);
				}
			});
		}
	}
	
	public void updateDial(String dial, String name) {
		Dial dialToUpdate = this.getDial(dial);
		dialToUpdate.setName(name);
		this.notifyObservers();
	}

	@Override
	public void notifyObservers() {
		for (IObserver observer : this.observers) {
			observer.update();
		}
	}

	@Override
	public void addObserver(IObserver observer) {
		this.observers.add(observer);

	}

	@Override
	public void removeObserver(IObserver observer) {
		this.observers.remove(observer);
	}
	
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    
	public int getDialIndex() {
		return dialIndex;
	}

	public void setDialIndex(int dialIndex) {
		this.dialIndex = dialIndex;
	}

	public Boolean getRadioOn() {
		return radioOn;
	}

	public void setRadioOn(Boolean radioOn) {
		this.radioOn = radioOn;
	}

	public List<Dial> getDials() {
		return dials;
	}

	public void setDials(List<Dial> dials) {
		this.dials = dials;
	}
}
